home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / spy.vs.bob / score.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  7.3 KB  |  310 lines

  1. /*
  2.  * SvB score file
  3.  */
  4. /*
  5.  * Copyright 1992 David Lemke and Network Computing Devices
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and its
  8.  * documentation for any purpose is hereby granted without fee, provided that
  9.  * the above copyright notice appear in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of Network Computing Devices not be
  12.  * used in advertising or publicity pertaining to distribution of the
  13.  * software without specific, written prior permission.  Network Computing
  14.  * Devices makes no representations about the suitability of this software
  15.  * for any purpose.  It is provided "as is" without express or implied
  16.  * warranty.
  17.  *
  18.  * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  19.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  20.  * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
  21.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  22.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  23.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24.  * OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * Author:
  27.  *        Dave Lemke
  28.  *        lemke@ncd.com
  29.  *
  30.  *        Network Computing Devices, Inc
  31.  *        350 North Bernardo Ave
  32.  *        Mountain View, CA 94043
  33.  *
  34.  *    @(#)score.c    1.3    92/01/20
  35.  *
  36.  */
  37.  
  38. #include    <stdio.h>
  39. #include    <X11/Xos.h>
  40. #include    <X11/Xlib.h>
  41. #include    <X11/Xutil.h>
  42. #include    <sys/file.h>
  43.  
  44. extern Display *dpy;
  45. extern Window game_win;
  46. extern GC   text_gc;
  47.  
  48. extern char user_name[];
  49. extern int  highscore;
  50.  
  51. extern char get_key();
  52.  
  53. static void find_personal_best();
  54. static void draw_scores();
  55.  
  56. void        update_scores();
  57.  
  58. #define    NUM_TOP_SCORES    25
  59. #define    SCORES_PER_USER    5
  60.  
  61. #define    SCORE_Y_INC    15
  62. #define    TOP_SCORE_Y    30
  63. #define    PERSONAL_SCORE_Y    (3 * TOP_SCORE_Y + (NUM_TOP_SCORES * SCORE_Y_INC))
  64. #define    SCORE_X        10
  65.  
  66. #define    MESSAGE_Y    (PERSONAL_SCORE_Y + (SCORES_PER_USER + 1) * SCORE_Y_INC)
  67.  
  68. #ifndef SCOREFILE
  69. #define    SCOREFILE    "/tmp/svb.scores"
  70. #endif
  71.  
  72. typedef struct _score {
  73.     char        name[40];
  74.     int         score;
  75.     int         ledge;
  76. }           Score;
  77.  
  78. Score       top_scores[NUM_TOP_SCORES];
  79. Score       personal[SCORES_PER_USER];
  80. Bool        read_scores = False;
  81.  
  82. static void
  83. wait_for_key()
  84. {
  85.     XEvent      ev;
  86.     char        c;
  87.  
  88.     while (1) {
  89.     XNextEvent(dpy, &ev);
  90.     if (ev.type == Expose && ev.xexpose.count == 0)
  91.         draw_scores();
  92.     else if (ev.type == KeyPress) {
  93.         c = get_key((XKeyPressedEvent *) & ev);
  94.         if (c == 'q')
  95.         exit(0);
  96.         else if (c == 'h') {
  97.         update_scores();
  98.         draw_scores();
  99.         } else if (c == ' ' || c == 's')
  100.         return;
  101.     }
  102.     }
  103. }
  104.  
  105. static void
  106. draw_scores()
  107. {
  108.     int         i,
  109.                 y;
  110.     char        scorebuf[256];
  111.  
  112.     XClearWindow(dpy, game_win);
  113.     sprintf(scorebuf, "%40s", "Top Scores");
  114.     XDrawImageString(dpy, game_win, text_gc, SCORE_X, 15,
  115.              scorebuf, strlen(scorebuf));
  116.     y = TOP_SCORE_Y;
  117.     for (i = 0; i < NUM_TOP_SCORES; i++) {
  118.     sprintf(scorebuf, "          %2d  %30s  %7d   Ledge %3d",
  119.         i + 1, top_scores[i].name, top_scores[i].score,
  120.         top_scores[i].ledge);
  121.     XDrawImageString(dpy, game_win, text_gc, SCORE_X, y,
  122.              scorebuf, strlen(scorebuf));
  123.     y += SCORE_Y_INC;
  124.     }
  125.     sprintf(scorebuf, "%40s", "Personal Top Scores");
  126.     y = PERSONAL_SCORE_Y;
  127.     XDrawImageString(dpy, game_win, text_gc, SCORE_X, y - 2 * SCORE_Y_INC,
  128.              scorebuf, strlen(scorebuf));
  129.     for (i = 0; i < SCORES_PER_USER; i++) {
  130.     sprintf(scorebuf, "          %2d  %30s  %7d   Ledge %3d",
  131.         i + 1, personal[i].name, personal[i].score,
  132.         personal[i].ledge);
  133.     XDrawImageString(dpy, game_win, text_gc, SCORE_X, y,
  134.              scorebuf, strlen(scorebuf));
  135.     y += SCORE_Y_INC;
  136.     }
  137.  
  138.     sprintf(scorebuf, "          'q' to Quit, 's' to Start");
  139.     XDrawImageString(dpy, game_win, text_gc, SCORE_X, MESSAGE_Y,
  140.              scorebuf, strlen(scorebuf));
  141. }
  142.  
  143. static void
  144. find_personal_best()
  145. {
  146.     int         i,
  147.                 j;
  148.  
  149.     for (i = 0; i < SCORES_PER_USER; i++) {
  150.     strcpy(personal[i].name, user_name);
  151.     personal[i].score = 0;
  152.     personal[i].ledge = 0;
  153.     }
  154.     for (i = 0, j = 0; i < NUM_TOP_SCORES; i++) {
  155.     if (strcmp(top_scores[i].name, user_name) == 0) {
  156.         personal[j].score = top_scores[i].score;
  157.         personal[j].ledge = top_scores[i].ledge;
  158.         j++;
  159.         if (j == SCORES_PER_USER)
  160.         return;;
  161.     }
  162.     }
  163. }
  164.  
  165. /*
  166.  * reads/inits score file
  167.  */
  168. void
  169. update_scores()
  170. {
  171.     FILE       *fp;
  172.     int         i;
  173.     char        buf[256];
  174.  
  175.     fp = fopen(SCOREFILE, "r");
  176.     if (fp) {
  177. #ifdef SYSV
  178.     long    fsize;
  179.  
  180.     fsize = fseek(fp, 0L, 2);
  181.     (void) fseek(fp, 0L, 0);
  182.     lockf(fileno(fp), F_LOCK, fsize);
  183. #else /*SYSV*/
  184.     flock(fileno(fp), LOCK_EX);
  185. #endif /*SYSV*/
  186.     i = 0;
  187.     while (fgets(buf, 256, fp)) {
  188.         sscanf(buf, "%s %d %d", top_scores[i].name, &top_scores[i].score,
  189.            &top_scores[i].ledge);
  190.         i++;
  191.     }
  192.     if (!read_scores)
  193.         find_personal_best();
  194.     fclose(fp);
  195.     } else {
  196.     /* do reinit if already running and unreadable file */
  197.     if (read_scores)
  198.         return;
  199.     for (i = 0; i < NUM_TOP_SCORES; i++) {
  200.         strcpy(top_scores[i].name, "Nobody");
  201.         top_scores[i].score = 0;
  202.         top_scores[i].ledge = 0;
  203.     }
  204.     for (i = 0; i < SCORES_PER_USER; i++) {
  205.         strcpy(personal[i].name, user_name);
  206.         personal[i].score = 0;
  207.         personal[i].ledge = 0;
  208.     }
  209.     }
  210.     read_scores = True;
  211.     highscore = personal[0].score;
  212. }
  213.  
  214. /*
  215.  * displays all current scores
  216.  */
  217. void
  218. show_scores()
  219. {
  220.     update_scores();
  221.     draw_scores();
  222.     wait_for_key();
  223. }
  224.  
  225. static void
  226. write_scores()
  227. {
  228.     FILE       *fp;
  229.     int         i;
  230.  
  231.     fp = fopen(SCOREFILE, "w");
  232.     if (fp) {
  233. #ifdef SYSV
  234.     long    fsize;
  235.  
  236.     fsize = fseek(fp, 0L, 2);
  237.     (void) fseek(fp, 0L, 0);
  238.     lockf(fileno(fp), F_LOCK, fsize);
  239. #else /*SYSV*/
  240.     flock(fileno(fp), LOCK_EX);
  241. #endif /*SYSV*/
  242.     for (i = 0; i < NUM_TOP_SCORES; i++)
  243.         fprintf(fp, "%s %d %d\n", top_scores[i].name,
  244.             top_scores[i].score, top_scores[i].ledge);
  245.     fclose(fp);
  246.     }
  247. }
  248.  
  249. /*
  250.  * adds score to table
  251.  */
  252. add_score(sc, ledge)
  253.     int         sc;
  254.     int         ledge;
  255. {
  256.     int         i,
  257.                 j;
  258.     int         user_count = 0;
  259.     int         replace;
  260.     int         low_user = 0;
  261.  
  262.     update_scores();        /* make sure they're up-to-date */
  263.     for (i = 0; i < NUM_TOP_SCORES; i++) {
  264.     if (strcmp(top_scores[i].name, user_name) == 0) {
  265.         user_count++;
  266.         low_user = top_scores[i].score;
  267.         replace = i;
  268.     }
  269.     }
  270.  
  271.     /*
  272.      * punt if we have the full number of scores && the new one is too low to
  273.      * care about
  274.      */
  275.     if (user_count >= SCORES_PER_USER) {
  276.     if (sc <= low_user) {
  277.         return;
  278.     }
  279.     } else {
  280.     replace = NUM_TOP_SCORES - 1;
  281.     }
  282.  
  283.     for (i = 0; i < NUM_TOP_SCORES; i++) {
  284.     if (sc > top_scores[i].score) {
  285.         for (j = replace; j > i; j--) {
  286.         strcpy(top_scores[j].name, top_scores[j - 1].name);
  287.         top_scores[j].score = top_scores[j - 1].score;
  288.         top_scores[j].ledge = top_scores[j - 1].ledge;
  289.         }
  290.         strcpy(top_scores[i].name, user_name);
  291.         top_scores[i].score = sc;
  292.         top_scores[i].ledge = ledge;
  293.         break;
  294.     }
  295.     }
  296.     for (i = 0; i < SCORES_PER_USER; i++) {
  297.     if (sc > personal[i].score) {
  298.         for (j = SCORES_PER_USER - 1; j > i; j--) {
  299.         personal[j].score = personal[j - 1].score;
  300.         personal[j].ledge = personal[j - 1].ledge;
  301.         }
  302.         personal[i].score = sc;
  303.         personal[i].ledge = ledge;
  304.         break;
  305.     }
  306.     }
  307.     highscore = personal[0].score;
  308.     write_scores();
  309. }
  310.